package cn.edu.nwpu.warehousemanagement.handler;

import cn.edu.nwpu.warehousemanagement.pojo.Result;
import cn.edu.nwpu.warehousemanagement.util.LogUtil;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 全局异常处理类
 *
 * @author Loadstar
 * @version 1.0
 */

@Hidden
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    /**
     * 输入非法
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<?> handleConstraintViolationException(ConstraintViolationException e, HttpServletResponse response) {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);//400
        LogUtil.error(GlobalExceptionHandler.class, "输入非法", e);
        return Result.error("输入非法" + (StringUtils.hasLength(e.getMessage()) ? e.getMessage() : ""));
        //StringUtils.hasLength 和 isBlank isEmpty有什么优势？
        //及检查是否为null，又检查length是否为0，但不检查是否全为空白符

    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletResponse response) {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);//400
        LogUtil.error(GlobalExceptionHandler.class, "输入非法", e);
//        return Result.error("输入非法，请求的参数不正确");//太简单了

        // 详细提取字段错误信息 又会透露内部实现
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        List<String> errorMessages = fieldErrors.stream()
                .map(this::formatFieldError)
                .toList();

        // 返回结构化的错误信息
        return Result.error("参数校验失败:" + errorMessages);

    }

    private String formatFieldError(FieldError fieldError) {
        String fieldName = fieldError.getField();
        String defaultMessage = fieldError.getDefaultMessage();

        return switch (fieldName) {
            case "role" -> "角色值无效，必须为 ADMIN、WAREHOUSE_MGR、BUYER 或 COURIER";
            case "username" -> "用户名长度必须在 5 到 20 个字符之间";
            case "password" -> "密码长度必须在 5 到 16 个字符之间";
            case "realname" -> "真实姓名长度必须在 1 到 16 个字符之间";
            case "phone" -> "手机号格式不正确";
            case "email" -> "邮箱格式不正确";
            default -> fieldName + ": " + defaultMessage;
        };
    }

    @ExceptionHandler(Exception.class)
    public Result<?> handleException(Exception e, HttpServletResponse response) {
//        log.error(e.getMessage());
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);//500
        LogUtil.error(GlobalExceptionHandler.class, "错误发生", e);
//        return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "发生错误");
        return Result.error("发生错误");

    }
}
